package com.hgy.commonsale.utils;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class FileUtils {

	private static final Log logger = LogFactory.getLog(FileUtils.class);

	private static final String FILE_ENCODING = "utf-8";

	public static String[] listFilenames(String path, final String pattern) throws IOException {
		File dir = new File(path);
		if (!dir.isDirectory() || !dir.exists())
			throw new IOException(path + " is not a valid path!");

		if (pattern == null) {
			return dir.list();
		} else {
			return dir.list(new FilenameFilter() {
				public boolean accept(File dir, String fileName) {
					return fileName.matches(pattern);
				}

			});
		}
	}

	public static File[] listFiles(String path, final String pattern) throws IOException {
		File dir = new File(path);
		if (!dir.isDirectory() || !dir.exists())
			throw new IOException(path + " is not a valid path!");

		if (pattern == null) {
			return dir.listFiles();
		} else {
			return dir.listFiles(new FilenameFilter() {

				public boolean accept(File dir, String fileName) {
					return fileName.matches(pattern);
				}

			});
		}
	}

	public static void copyTo(String fullSourceFileName, String fullDestFileName) throws IOException {
		InputStream is = null;
		OutputStream fs = null;
		try {
			is = new FileInputStream(fullSourceFileName);
			fs = new FileOutputStream(fullDestFileName);
			int byteread;
			byte[] buffer = new byte[1444];
			while ((byteread = is.read(buffer)) != -1) {
				fs.write(buffer, 0, byteread);
			}
		} finally {
			if (is != null) {
				try {
					is.close();
				} catch (IOException e) {
					logger.error(e.getMessage(), e);
				}
			}
			if (fs != null) {
				try {
					fs.close();
				} catch (IOException e) {
					logger.error(e.getMessage(), e);
				}
			}
		}
	}

	public static void deleteDir(String dir) throws IOException {
		File file = new File(dir);
		if (!file.isDirectory() || !file.exists())
			throw new IOException(dir + " is not a valid directory!");
		file.delete();
	}

	public static void deleteFile(String fullFileName) throws IOException {
		File file = new File(fullFileName);
		if (!file.isFile() || !file.exists())
			throw new IOException(fullFileName + " is not a valid file!");
		file.delete();
	}

	public static void deleteAllFile(String dir, String pattern) throws IOException {
		String[] files = listFilenames(dir, pattern);
		if (!dir.endsWith(File.separator))
			dir += File.separator;
		if (files != null) {
			for (int i = 0; i < files.length; i++) {
				deleteFile(dir + files[i]);
			}
		}
	}

	public static void renameFile(String fullFilename, String fullNewFilename) throws IOException {
		File file = new File(fullFilename);
		if (!file.isFile() || !file.exists())
			throw new IOException(fullFilename + " is not a valid file!");
		file.renameTo(new File(fullNewFilename));
	}

	private static void writeBufferedTextFile(File file, String charsetName, ITextFileWriter ifileWriter)
			throws IOException {
		FileOutputStream fo = null;
		try {
			fo = new FileOutputStream(file);
			OutputStreamWriter ow = null;
			try {
				ow = new OutputStreamWriter(fo, charsetName);
				BufferedWriter bw = null;
				try {
					bw = new BufferedWriter(ow);
					ifileWriter.write(bw);
				} finally {
					if (bw != null) {
						try {
							bw.close();
						} catch (IOException e) {
							logger.error(e.getMessage(), e);
						}
					}
				}
			} finally {
				if (ow != null) {
					try {
						ow.close();
					} catch (IOException e) {
						logger.error(e.getMessage(), e);
					}
				}
			}
		} finally {
			if (fo != null) {
				try {
					fo.close();
				} catch (IOException e) {
					logger.error(e.getMessage(), e);
				}
			}
		}
	}

	public static File writeBufferedTempTextFile(String prefix, String suffix, String charsetName,
			ITextFileWriter ifileWriter) throws IOException {
		File tempFile = File.createTempFile(prefix, suffix);
		writeBufferedTextFile(tempFile, charsetName, ifileWriter);
		return tempFile;
	}

	public static File writeBufferedTextFile(String fullFileName, String charsetName, ITextFileWriter ifileWriter)
			throws IOException {
		File file = new File(fullFileName);
		writeBufferedTextFile(file, charsetName, ifileWriter);
		return file;
	}

	public static void readBufferedTextFile(InputStream in, String charsetName, ITextFileReader ifileReader)
			throws IOException {
		InputStreamReader inr = null;
		try {
			inr = new InputStreamReader(in, charsetName);
			BufferedReader br = null;
			try {
				br = new BufferedReader(inr);
				ifileReader.read(br);
			} finally {
				if (br != null) {
					try {
						br.close();
					} catch (IOException e) {
						logger.error(e.getMessage(), e);
					}
				}
			}
		} finally {
			if (inr != null) {
				try {
					inr.close();
				} catch (IOException e) {
					logger.error(e.getMessage(), e);
				}
			}
		}
	}

	public static void readBufferedTextFile(String fullFileName, String charsetName, ITextFileReader ifileReader)
			throws IOException {
		File inputFile = new File(fullFileName);
		if (inputFile.isDirectory() || !inputFile.exists())
			throw new IOException(fullFileName + " is not a vaild file!");

		FileInputStream fin = null;
		try {
			fin = new FileInputStream(inputFile);
			readBufferedTextFile(fin, charsetName, ifileReader);
		} finally {
			if (fin != null) {
				try {
					fin.close();
				} catch (IOException e) {
					logger.error(e.getMessage(), e);
				}
			}
		}
	}

	public static String getPostfix(String filename) {
		if (filename == null)
			return null;
		int pos = filename.lastIndexOf('.');
		if (pos == -1)
			return null;
		return filename.substring(filename.lastIndexOf('.') + 1);
	}

	public static void unZipFile(File zipFile, String dir) throws IOException {
		// check if it's a zip file.
		ZipFile zip = new ZipFile(zipFile.getCanonicalPath());
		zip.close();
		ZipInputStream inputStream = new ZipInputStream(new FileInputStream(zipFile));
		File newdir = new File(dir);
		if (!newdir.exists())
			newdir.mkdir();
		byte[] bytes = new byte[1024];
		int slen;
		ZipEntry file = inputStream.getNextEntry();
		while (file != null) {
			FileOutputStream out = new FileOutputStream(dir + File.separator + file.getName());
			while ((slen = inputStream.read(bytes, 0, bytes.length)) != -1) {
				out.write(bytes, 0, slen);
			}
			out.close();
			file = inputStream.getNextEntry();
		}
		inputStream.close();
	}

	public static void moveFileToDir(File file, String dirPath) {
		if (dirPath == null)
			throw new IllegalArgumentException("Please provide the directory to move to");

		FileInputStream inFile = null;
		FileOutputStream outFile = null;
		try {
			if (!dirPath.endsWith(File.separator)) {
				dirPath += File.separator;
			}
			File bak = new File(dirPath);
			if (!bak.exists()) {
				bak.mkdirs();
			}
			File out = new File(dirPath + file.getName());
			inFile = new FileInputStream(file);
			outFile = new FileOutputStream(out);
			byte[] buffer = new byte[1024];
			int i = 0;
			while ((i = inFile.read(buffer)) != -1) {
				outFile.write(buffer, 0, i);
			}
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
		} finally {
			try {
				if (inFile != null)
					inFile.close();
				if (outFile != null)
					outFile.close();
				file.delete();
			} catch (IOException e) {
				logger.error(e.getMessage(), e);
			}
		}
	}

	public static void writeToFile(File dataFile, String wirteString) {
		if (!dataFile.exists()) {
			try {
				dataFile.getParentFile().mkdirs();
				dataFile.createNewFile();
			} catch (IOException e) {
				logger.error(e.getMessage(), e);
			}
		}
		try {
			org.apache.commons.io.FileUtils.writeStringToFile(dataFile, wirteString, FILE_ENCODING);
		} catch (IOException e) {
			logger.error(e.getMessage(), e);
		}

	}

	public static String initDirPath(String path) {
		if (path == null)
			throw new IllegalArgumentException("Please initialize incoming message source folder path!");

		if (!path.endsWith(File.separator))
			path += File.separator;

		File file = new File(path);
		if (!file.exists())
			file.mkdirs();
		return path;
	}

}
